﻿#include "CKeyboard.h"

CKeyboard::CKeyboard(HINSTANCE hIns,HWND hWnd) {
	this->di8 = 0;
	this->did8 = 0;
	this->hInstance = hIns;
	this->hwnd = hWnd;
	ZeroMemory(&this->key_buffer,sizeof(key_buffer));
}

CKeyboard::~CKeyboard(void) {

}

bool CKeyboard::Init() {
	HRESULT hr = DirectInput8Create(
					this->hInstance, // hInstance của chương trình
					DIRECTINPUT_VERSION, // tham số mặc định
					IID_IDirectInput8, // tham số mặc định
					(void**)&this->di8, // con trỏ nhận dữ liệu trả về
					NULL // tham số dùng thêm
					);
	if(FAILED(hr)) {
		return false;
	}
	// tạo bàn phím. GUID_SysKeyboard là chỉ bàn phím.
	hr = this->di8->CreateDevice(GUID_SysKeyboard,&this->did8,NULL);
	if(FAILED(hr)) {
		return false;
	}
	// dạng dữ liệu sẽ được nhận
	hr = this->did8->SetDataFormat(&c_dfDIKeyboard);
	if(FAILED(hr)) {
		return false;
	}
	// loại hoạt động. DISCL_FOREGROUND nghĩa là chỉ hoạt động khi cửa sổ hwnd đang được handle
	hr = this->did8->SetCooperativeLevel(this->hwnd,DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
	if(FAILED(hr)) {
		return false;
	}
	// yêu cầu thiết bị
	hr = this->did8->Acquire();
	if(FAILED(hr)) {
		return false;
	}
	return true;
}

void CKeyboard::GetState() {
	// xóa trạng thái bạn phím
	ZeroMemory(&this->key_buffer,sizeof(this->key_buffer));
	// lấy trạng thái của bàn phím
	HRESULT hr = this->did8->GetDeviceState(sizeof(this->key_buffer),(LPVOID)&this->key_buffer);
	if(FAILED(hr)) {
		// nếu bàn phím đang bị nhả ra thì yêu cầu lại
		//while(this->did8->Acquire() == DIERR_INPUTLOST);
		do
		{
			hr = this->did8->Acquire();
		}while(hr == DIERR_INPUTLOST );
		// If we failed for some other reason, simply return out of method
		if( FAILED(hr) )
			return;
		// Read the current keyboard state
		this->did8->GetDeviceState( sizeof(this->key_buffer), &this->key_buffer);
	}
}

bool CKeyboard::IsKeyDown(int key) {
	// trả về phím có được nhấn hay không, 0x80 nhằm xác định giá trị các bit đầu tiên
	return (key_buffer[key] & 0x8000) != 0;
}

void CKeyboard::Shutdown() {
	if(this->di8) {
		this->di8->Release();
		this->di8 = NULL;
	}
	if(this->did8) {
		this->did8->Release();
		this->did8 = NULL;
	}
}
